package com.liujit.upms.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liujit.common.constants.ColumnConstant;
import com.liujit.common.constants.GlobalConstant;
import com.liujit.common.domain.params.DelParams;
import com.liujit.common.domain.result.PageBean;
import com.liujit.common.exception.DataNotFoundException;
import com.liujit.common.utils.DozerConvertor;
import com.liujit.common.utils.Pagination;
import com.liujit.upms.domain.model.SysDictItem;
import com.liujit.upms.domain.model.SysLog;
import com.liujit.upms.domain.model.SysMenu;
import com.liujit.upms.domain.params.SysLogParams;
import com.liujit.upms.domain.query.SysLogQuery;
import com.liujit.upms.domain.result.SysLogResult;
import com.liujit.upms.mapper.SysLogMapper;
import com.liujit.upms.service.SysDictItemService;
import com.liujit.upms.service.SysLogService;
import com.liujit.upms.service.SysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Description 系统日志Service实现类
 * @Author liujun
 * @Date 2021-06-26 15:45:43
 */
@Service
public class SysLogServiceImpl extends ServiceImpl<SysLogMapper, SysLog> implements SysLogService {

    private SysMenuService sysMenuService;

    private SysDictItemService sysDictItemService;

    @Autowired
    public void setSysMenuService(SysMenuService sysMenuService) {
        this.sysMenuService = sysMenuService;
    }

    @Autowired
    public void setSysDictItemService(SysDictItemService sysDictItemService) {
        this.sysDictItemService = sysDictItemService;
    }

    @Override
    public PageBean<SysLogResult> getOperationPage(SysLogQuery query) {
        // 排序
        if (StrUtil.isNotBlank(query.getSortName()) && StrUtil.isNotBlank(query.getSortOrder())) {
            query.setSortName(ColumnConstant.REQ_TIME);
            query.setSortOrder(SqlKeyword.DESC.getSqlSegment());
        }
        Page<SysLog> page = Pagination.page(query);
        LambdaQueryWrapper<SysLog> wrapper = this.getWrapper(query);
        wrapper.le(SysLog::getRespCode, 1);
        IPage<SysLog> iPage = super.page(page, wrapper);
        return PageBean.page(iPage, SysLogResult.class);
    }

    @Override
    public PageBean<SysLogResult> getExceptionPage(SysLogQuery query) {
        Page<SysLog> page = Pagination.page(query);
        LambdaQueryWrapper<SysLog> wrapper = this.getWrapper(query);
        wrapper.gt(SysLog::getRespCode, 1);
        IPage<SysLog> iPage = super.page(page, wrapper);
        return PageBean.page(iPage, SysLogResult.class);
    }

    @Override
    public Boolean add(SysLogParams param) {
        SysLog entity = DozerConvertor.convertor(param, SysLog.class);
        // 判断请求来源
        if (GlobalConstant.ADMIN_CLIENT.equals(param.getClientId())) {
            // 根据菜单id，查询菜单名称
            if (param.getMenuId() == 1) {
                entity.setDescription("系统操作");
            } else {
                LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
                wrapper.select(SysMenu::getName);
                wrapper.eq(SysMenu::getId, param.getMenuId());
                String name = sysMenuService.getObj(wrapper, item -> Convert.toStr(item));
                entity.setDescription(name);
            }
        } else {
            // 根据菜单id，查询菜单名称
            if (param.getMenuId() == 1) {
                entity.setDescription("系统操作");
            } else {
                LambdaQueryWrapper<SysDictItem> wrapper = new LambdaQueryWrapper<>();
                wrapper.select(SysDictItem::getLabel);
                wrapper.eq(SysDictItem::getId, param.getMenuId());
                String name = sysDictItemService.getObj(wrapper, item -> Convert.toStr(item));
                entity.setDescription(name);
            }
        }
        return super.save(entity);
    }

    @Override
    public SysLogResult get(Long id) {
        SysLog sysLog = super.getById(id);
        if (sysLog == null) {
            throw new DataNotFoundException();
        }
        return DozerConvertor.convertor(sysLog, SysLogResult.class);
    }

    @Override
    public Boolean del(DelParams params) {
        if (CollectionUtil.isNotEmpty(params.getIds())) {
            return super.removeByIds(params.getIds());
        }
        return super.removeById(params.getId());
    }

    private LambdaQueryWrapper<SysLog> getWrapper(SysLogQuery query) {
        LambdaQueryWrapper<SysLog> wrapper = new LambdaQueryWrapper();
        if (StrUtil.isNotBlank(query.getClientId())) {
            wrapper.like(SysLog::getClientId, query.getClientId());
        }
        if (StrUtil.isNotBlank(query.getServiceId())) {
            wrapper.like(SysLog::getServiceId, query.getServiceId());
        }
        if (StrUtil.isNotBlank(query.getAccount())) {
            wrapper.like(SysLog::getAccount, query.getAccount());
        }
        if (StrUtil.isNotBlank(query.getDescription())) {
            wrapper.like(SysLog::getDescription, query.getDescription());
        }
        if (StrUtil.isNotBlank(query.getVisitCode())) {
            wrapper.like(SysLog::getVisitCode, query.getVisitCode());
        }
        if (StrUtil.isNotBlank(query.getIp())) {
            wrapper.like(SysLog::getIp, query.getIp());
        }
        if (StrUtil.isNotBlank(query.getLocation())) {
            wrapper.like(SysLog::getLocation, query.getLocation());
        }
        if (StrUtil.isNotBlank(query.getReqUrl())) {
            wrapper.like(SysLog::getReqUrl, query.getReqUrl());
        }
        if (query.getRespCode() != null) {
            wrapper.eq(SysLog::getRespCode, query.getRespCode());
        }
        if (query.getStartTime() != null) {
            wrapper.ge(SysLog::getReqTime, query.getStartTime());
        }
        if (query.getEndTime() != null) {
            wrapper.le(SysLog::getReqTime, query.getEndTime());
        }
        return wrapper;
    }
}
